﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using Microsoft.Extensions.Hosting;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class StocktakingOrderService : BaseService, IStocktakingOrderService
    {
        private readonly IStocktakingOrderDetailRepository _stocktakingOrderDetailRepository;
        private readonly IStocktakeResultRecordRepository _stocktakeResultRecordRepository;
        private readonly IStocktakingOrderRepository _stocktakingOrderRepository;
        private readonly IInventoryLogRepository _inventoryLogRepository;
        private readonly IPickingOrderRepository _pickingOrderRepository;
        private readonly IPutawayOrderRepository _putawayOrderRepository;
        private readonly IInventoryRepository _inventoryRepository;
        private readonly IInstructRepository _instructRepository;
        private readonly IUnitOfWork _unitOfWork;
        public StocktakingOrderService(IMapper mapper, IStocktakingOrderRepository _stocktakingOrderRepository, IStocktakingOrderDetailRepository _stocktakingOrderDetailRepository, IUnitOfWork _unitOfWork, IInventoryRepository _inventoryRepository, IInstructRepository _instructRepository, IPickingOrderRepository _pickingOrderRepository, IInventoryLogRepository _inventoryLogRepository, IPutawayOrderRepository _putawayOrderRepository, IStocktakeResultRecordRepository _stocktakeResultRecordRepository) : base(mapper)
        {
            this._stocktakingOrderDetailRepository = _stocktakingOrderDetailRepository;
            this._stocktakeResultRecordRepository = _stocktakeResultRecordRepository;
            this._stocktakingOrderRepository = _stocktakingOrderRepository;
            this._inventoryLogRepository = _inventoryLogRepository;
            this._pickingOrderRepository = _pickingOrderRepository;
            this._putawayOrderRepository = _putawayOrderRepository;
            this._inventoryRepository = _inventoryRepository;
            this._instructRepository = _instructRepository;
            this._unitOfWork = _unitOfWork;
        }

        #region PC
        public bool AddStocktakingOrder(StocktakingOrder m, out string message)
        {
            message = string.Empty;
            bool result = false;
            _unitOfWork.BeginTransaction();
            try
            {
                foreach (var item in m.StocktakingOrderDetailList)
                {
                    if (item.InventoryId == null)
                    {
                        message = "库存Id有误！";
                        return false;
                    }
                    var invobj = _inventoryRepository.QueryEntityById((long)item.InventoryId);
                    if (invobj == null)
                    {
                        message = "找不到库存信息！";
                        return false;
                    }
                    else
                    {
                        invobj.IsLock = true;
                        _inventoryRepository.UpdEntity(invobj);
                    }
                    m.WarehouseId = invobj.WarehouseId ?? 0;
                    m.WarehouseName = invobj.WarehouseName;
                    m.WarehouseCode = invobj.WarehouseCode;
                    m.AreaId = invobj.AreaId;
                    m.AreaName = invobj.AreaName;
                    m.AreaCode = invobj.AreaCode;
                    m.MaterialId = invobj.MaterialId;
                    m.MaterialName = invobj.MaterialName;
                    m.BatchNo = invobj.BatchNo;
                    _stocktakingOrderRepository.AddEntity(m);
                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                        break;
                    item.OrderDetailId = m.Id;
                    item.OrderSn = m.OrderSn;
                    item.CellId = invobj.LocationId;
                    item.CellCode = invobj.LocationCode;
                    item.LocationName = invobj.LocationName;
                    item.CellDepthIndex = invobj.LocationDepth;
                    item.PalletBarcode = invobj.PalletBarcode;
                    item.MaterialId = invobj.MaterialId;
                    item.MaterialCode = invobj.MaterialCode;
                    item.MaterialName = invobj.MaterialName;
                    item.Qty = invobj.AvailableQty;
                    item.BatchNo = invobj.BatchNo;
                    item.ExpireDate = invobj.ExpireDate;
                    item.ProductDate = invobj.ProductDate;
                    item.WarehouseId = invobj.WarehouseId;                 
                    item.MaterialTypeId = invobj.MaterialTypeId;
                    item.MaterialTypeName = invobj.MaterialTypeName;
                    _stocktakingOrderDetailRepository.AddEntity(item);
                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                        break;
                }
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public bool DelStocktakingOrder(long id, out string message)
        {
            message = string.Empty;
            var sobj = _stocktakingOrderRepository.QueryEntityById(id);
            if (sobj == null)
            {
                message = "找不到盘点单！";
                return false;
            }
            if (sobj.Status == 3 || sobj.Status == 4)
            {
                message = "作业中或已完成的订单不可删除！";
                return false;
            }

            _stocktakingOrderRepository.DelEntity(sobj);
            var sdobj = _stocktakingOrderDetailRepository.QueryEntityWhere(x => x.OrderDetailId == sobj.Id);
            if (sdobj == null)
            {
                message = "找不到盘点单明细！";
                return false;
            }
            _stocktakingOrderDetailRepository.DelEntity(sdobj);

            var invobj = _inventoryRepository.QueryEntityById(sdobj.InventoryId ?? 0);
            if (invobj == null)
            {
                message = "找不到库存信息！";
                return false;
            }
            invobj.IsLock = false;
            invobj.Status = 1;
            _inventoryRepository.UpdEntity(invobj);
            return _unitOfWork.SaveChangesEntity();
        }

        public StocktakingOrder? GetStocktakingOrderById(long id)
        {
            var sobj = _stocktakingOrderRepository.QueryEntityById(id);
            if (sobj == null)
                return null;
            var sdlist = _stocktakingOrderDetailRepository.GetEntityWhereAll(x => x.OrderDetailId == sobj.Id);
            if (sdlist.Any())
                sobj.StocktakingOrderDetailList = sdlist.ToList();
            return sobj;
        }

        public List<StocktakingOrder> GetStocktakingOrderList(long? wid, long? aid, string? name, int? status, int pageIndex, int pageSize, out int totalCount)
        {
            var slist = _stocktakingOrderRepository.GetEntityAlls();

            if (wid != null)
                slist = slist.Where(x => x.WarehouseId == (long)wid);

            if (aid != null)
                slist = slist.Where(x => x.AreaId == (long)aid);

            if (!string.IsNullOrEmpty(name))
                slist = slist.Where(x => x.Name.Contains(name));

            if (status != null)
                slist = slist.Where(x => x.Status == status);

            totalCount = slist.Count();

            var list = _stocktakingOrderRepository.GetEntityAlls(slist, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return list.ToList();
        }

        public bool UpdStocktakingOrder(StocktakingOrder m, out string message)
        {
            message = string.Empty;
            bool result = false;
            _unitOfWork.BeginTransaction();
            try
            {
                var sdobj = _stocktakingOrderDetailRepository.QueryEntityWhere(x => x.OrderDetailId == m.Id);
                if (sdobj != null)
                {
                    _stocktakingOrderDetailRepository.DelEntity(sdobj);
                    var uinvobj = _inventoryRepository.QueryEntityById(sdobj.InventoryId ?? 0);
                    if (uinvobj != null)
                    {
                        uinvobj.IsLock = false;
                        uinvobj.Status = 1;
                    }
                }
                foreach (var item in m.StocktakingOrderDetailList)
                {
                    if (item.InventoryId == null)
                    {
                        message = "库存Id有误！";
                        return false;
                    }
                    var invobj = _inventoryRepository.QueryEntityById((long)item.InventoryId);
                    if (invobj == null)
                    {
                        message = "找不到库存信息！";
                        return false;
                    }
                    else
                    {
                        invobj.IsLock = true;
                        _inventoryRepository.UpdEntity(invobj);
                    }
                    m.WarehouseId = invobj.WarehouseId ?? 0;
                    m.WarehouseName = invobj.WarehouseName;
                    m.WarehouseCode = invobj.WarehouseCode;
                    m.AreaId = invobj.AreaId;
                    m.AreaName = invobj.AreaName;
                    m.AreaCode = invobj.AreaCode;
                    m.MaterialId = invobj.MaterialId;
                    m.MaterialName = invobj.MaterialName;
                    m.BatchNo = invobj.BatchNo;
                    _stocktakingOrderRepository.UpdEntity(m);
                    item.OrderDetailId = m.Id;
                    item.OrderSn = m.OrderSn;
                    item.CellId = invobj.LocationId;
                    item.CellCode = invobj.LocationCode;
                    item.LocationName = invobj.LocationName;
                    item.CellDepthIndex = invobj.LocationDepth;
                    item.PalletBarcode = invobj.PalletBarcode;
                    item.MaterialId = invobj.MaterialId;
                    item.MaterialCode = invobj.MaterialCode;
                    item.MaterialName = invobj.MaterialName;
                    item.Qty = invobj.AvailableQty;
                    item.BatchNo = invobj.BatchNo;
                    item.ExpireDate = invobj.ExpireDate;
                    item.ProductDate = invobj.ProductDate;
                    item.WarehouseId = invobj.WarehouseId;               
                    item.MaterialTypeId = invobj.MaterialTypeId;
                    item.MaterialTypeName = invobj.MaterialTypeName;
                    _stocktakingOrderDetailRepository.AddEntity(item);
                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                        break;
                }
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }
        #endregion

        #region PDA
        public bool StartStocktakingOrder(StocktakingOrderDto m, out string message)
        {
            message = string.Empty;
            bool result = false;
            _unitOfWork.BeginTransaction();
            try
            {
                var sobj = _stocktakingOrderRepository.QueryEntityById(m.Id);
                if (sobj == null)
                {
                    message = "找不到盘点单！";
                    return false;
                }
                if (sobj.Status == 3)
                {
                    message = "该任务正在作业中！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (sobj.Status == 4)
                {
                    message = "该任务已完成！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                sobj.Status = 3;
                sobj.ExecDate = DateTime.Now;
                var sdobj = _stocktakingOrderDetailRepository.QueryEntityWhere(x => x.OrderDetailId == sobj.Id);
                if (sdobj == null)
                {
                    message = "找不到盘点单明细！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                sdobj.Status = 1;
                sdobj.Step = 1;
                var invobj = _inventoryRepository.QueryEntityById(sdobj.InventoryId ?? 0);
                if (invobj == null)
                {
                    message = "找不到库存信息！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                #region 如果浅深位有货物产生移库操作
                if (invobj.AreaCode.Contains('L'))
                {
                    //排
                    string rows = invobj.LocationCode.Substring(7, 1);
                    if (string.IsNullOrEmpty(rows))
                    {
                        message = "获取仓位排失败！";
                        return false;
                    }
                    if (rows == "1")
                    {
                        string[] parts = invobj.LocationCode.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_2_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "4")
                    {
                        string[] parts = invobj.LocationCode.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_3_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                }
                #endregion
                invobj.Status = 8;
                #region 添加指令
                Instruct inobj = new Instruct();
                inobj.WarehouseCode = invobj.WarehouseCode;
                inobj.Status = 2;
                inobj.FromLocation = "item.StationCode";
                inobj.ToLocation = invobj.LocationCode;
                inobj.WorkDeviceType = 1;
                inobj.InstructType = 5;
                inobj.Action = 0;
                inobj.RelatedOrderId = sobj.Id;
                inobj.ExpectedToLocation = invobj.LocationCode;
                inobj.InstructIndex = 1;
                inobj.PalletBarcode = invobj.PalletBarcode;
                inobj.ScanedBarcode = invobj.PalletBarcode;
                inobj.Priority = 9999;
                inobj.Qty = invobj.AvailableQty ?? 0;
                inobj.FinishedQty = 0;
                inobj.BusinessType = (int)EmBusinessType.Inventory;
                inobj.RelatedOrderDetailId = sdobj.Id;
                inobj.CreateUserId = m.NowUserId;
                inobj.CreateUserName = m.NowUserName;
                _instructRepository.AddEntity(inobj);
                #endregion
                #region 添加下架单
                string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                string pickCode = "STO" + str;
                PickingOrder pickOrder = new PickingOrder();
                pickOrder.Id = YitIdHelper.NextId();
                pickOrder.Code = pickCode;
                pickOrder.WarehouseCode = invobj.WarehouseCode;
                pickOrder.WarehouseName = invobj.WarehouseName;
                pickOrder.BillType = 3;
                pickOrder.DescAddress = "item.DescAddress";
                pickOrder.PalletBarcode = invobj.PalletBarcode;
                pickOrder.Roadway = invobj.LocationCode.Substring(5, 1); ;
                pickOrder.LocationCode = invobj.LocationCode;
                pickOrder.LocationDepth = invobj.LocationDepth;
                pickOrder.Status = 4;
                pickOrder.Qty = invobj.AvailableQty;
                pickOrder.MaterialId = invobj.MaterialId;
                pickOrder.MaterialCode = invobj.MaterialCode;
                pickOrder.MaterialName = invobj.MaterialName;
                pickOrder.MaterialKeyId = invobj.MaterialKeyId;
                pickOrder.BatchNo = invobj.BatchNo;
                pickOrder.SourceType = 4;
                pickOrder.RelatedOrderDetailId = sdobj.Id;
                pickOrder.CreateDate = DateTime.Now;
                _pickingOrderRepository.AddEntity(pickOrder);
                result = _unitOfWork.SaveChangesEntity();
                #endregion
                #region 堆垛机                

                #endregion
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        private bool StaticFinishStocktakingOrder(string pickcode, out string message)
        {
            message = "";
            var pickobj = _pickingOrderRepository.QueryEntityWhere(x => x.Code == pickcode && x.SourceType == 4 && x.Status == 4);
            if (pickobj == null)
            {
                message = "找不到下架单！";
                return false;
            }
            var instructlist = _instructRepository.GetEntityWhereAll(x => x.PalletBarcode == pickobj.PalletBarcode && x.Status == 2 && x.InstructType == 5).ToList();
            if (!instructlist.Any())
            {
                message = "未查询到指令！";
                return false;
            }
            bool result;
            try
            {
                foreach (var instruct in instructlist)
                {
                    instruct.Status = 4;
                    instruct.EndTime = DateTime.Now;
                    //盘点单id
                    long? sid = instruct.RelatedOrderId;
                    if (sid == null)
                    {
                        message = "盘点单id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var sobj = _stocktakingOrderRepository.QueryEntityById(sid ?? 0);
                    if (sobj == null)
                    {
                        message = "未查询到单号";
                        return false;
                    }
                    if (instruct.RelatedOrderDetailId == null)
                    {
                        message = "盘库单明细id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var sdobj = _stocktakingOrderDetailRepository.QueryEntityById((long)instruct.RelatedOrderDetailId);
                    if (sdobj == null)
                    {
                        message = "未查询到单号" + sobj.OrderSn + "的盘点单详情！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    sdobj.Step = 2;
                    //拿到库存id
                    long? invid = sdobj.InventoryId;
                    if (invid == null)
                    {
                        message = "出库明细中库存id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    Inventory? inventoryModel = _inventoryRepository.QueryEntityById((long)invid);
                    if (inventoryModel == null)
                    {
                        message = "未查询到库存信息！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    decimal? startQty = inventoryModel.AvailableQty;
                    decimal? changeQty = instruct.Qty;
                    #region 库存流水
                    //var inventoryLog = new InventoryLog
                    //{
                    //    Id = YitIdHelper.NextId(),
                    //    SourceType = 2,
                    //    SourceSn = sobj.OrderSn,
                    //    WarehouseId = inventoryModel.WarehouseId,
                    //    WarehouseName = inventoryModel.WarehouseName,
                    //    AreaName = inventoryModel.AreaName,
                    //    LocationCode = inventoryModel.LocationCode,
                    //    PalletBarcode = inventoryModel.PalletBarcode,
                    //    MaterialId = inventoryModel.MaterialId,
                    //    MaterialCode = inventoryModel.MaterialCode,
                    //    MaterialName = inventoryModel.MaterialName,
                    //    BatchNo = inventoryModel.BatchNo,
                    //    StartQty = startQty,
                    //    ChangeQty = -changeQty,
                    //    EndQty = startQty - changeQty,
                    //    BaseUnitId = inventoryModel.UnitId,
                    //    BaseUnitName = inventoryModel.UnitName,
                    //    CreateDate = DateTime.Now,
                    //};
                    //_inventoryLogRepository.AddEntity(inventoryLog);
                    #endregion
                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                    {
                        message = "保存库存流水失败！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                }
                var ilist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == pickobj.PalletBarcode);
                foreach (var item in ilist)
                {
                    if (item.AreaCode == "1")
                    {
                        item.Status = 1;
                        item.IsLock = false;
                    }
                    else
                    {
                        item.IsLock = false;
                    }
                }
                var picklist = _pickingOrderRepository.GetEntityWhereAll(x => x.SourceType == 4 && x.Status == 4 && x.PalletBarcode == pickobj.PalletBarcode);
                foreach (var item in picklist)
                {
                    item.Status = 5;
                    item.ModifyDate = DateTime.Now;
                    _pickingOrderRepository.UpdEntity(item);
                }
                if (!_unitOfWork.SaveChangesEntity())
                    return false;
                return true;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public bool FinishStocktakingOrder(string pickcode, out string message)
        {
            _unitOfWork.BeginTransaction();
            try
            {
                bool result = StaticFinishStocktakingOrder(pickcode, out message);
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public bool StartStocktakingOrders(StocktakingOrderDto m, out string message)
        {
            message = string.Empty;
            bool result = false;
            var sobj = _stocktakingOrderRepository.QueryEntityById(m.Id);
            if (sobj == null)
            {
                message = "找不到盘点单！";
                return false;
            }
            var sdobj = _stocktakingOrderDetailRepository.QueryEntityWhere(x => x.OrderDetailId == m.Id);
            if (sdobj == null)
            {
                message = "找不到盘点单明细！";
                return false;
            }
            if (sdobj.Step != 2)
            {
                message = "当前明细状态有误！";
                return false;
            }
            sdobj.Step = 3;
            //根据托盘查找库存数据
            var invobj = _inventoryRepository.QueryEntityById(sdobj.InventoryId ?? 0);
            if (invobj == null)
            {
                message = "找不到库存信息！";
                return false;
            }
            _unitOfWork.BeginTransaction();
            try
            {
                if (invobj == null)
                {
                    message = "未找到库存数据";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                #region 盘点结果
                StocktakeResultRecord stocktakeResultRecord = new StocktakeResultRecord();
                stocktakeResultRecord.OrderId = sobj.Id;
                stocktakeResultRecord.OrderSn = sobj.OrderSn;
                stocktakeResultRecord.WarehouseId = sobj.WarehouseId;
                stocktakeResultRecord.WarehouseName = sobj.WarehouseName;
                stocktakeResultRecord.AreaId = sobj.AreaId;
                stocktakeResultRecord.AreaName = sobj.AreaName;
                stocktakeResultRecord.CellId = sdobj.CellId;
                stocktakeResultRecord.CellCode = sdobj.CellCode;
                stocktakeResultRecord.CellDepthIndex = sdobj.CellDepthIndex;
                stocktakeResultRecord.PalletBarcode = sdobj.PalletBarcode;
                stocktakeResultRecord.MaterialId = sobj.MaterialId;
                stocktakeResultRecord.MaterialName = sobj.MaterialName;
                stocktakeResultRecord.MaterialBarcode = sobj.BatchNo;
                stocktakeResultRecord.OriginalQty = sdobj.Qty;
                stocktakeResultRecord.CountQty = m.Qty;
                stocktakeResultRecord.UnitId = invobj.UnitId;
                stocktakeResultRecord.UnitName = invobj.UnitName;
                stocktakeResultRecord.IsHandle = 0;
                if (sdobj.Qty == m.Qty)
                    stocktakeResultRecord.Status = 1;
                else if (sdobj.Qty < m.Qty)
                    stocktakeResultRecord.Status = 2;
                else
                    stocktakeResultRecord.Status = 3;
                _stocktakeResultRecordRepository.AddEntity(stocktakeResultRecord);
                #endregion
                #region 添加指令
                Instruct inobj = new Instruct();
                inobj.WarehouseCode = invobj.WarehouseCode;
                inobj.Status = 2;
                inobj.FromLocation = "item.StationCode";
                inobj.ToLocation = invobj.LocationCode;
                inobj.WorkDeviceType = 1;
                inobj.InstructType = 4;
                inobj.Action = 0;
                inobj.RelatedOrderId = sobj.Id;
                inobj.ExpectedToLocation = invobj.LocationCode;
                inobj.InstructIndex = 1;
                inobj.PalletBarcode = invobj.PalletBarcode;
                inobj.ScanedBarcode = invobj.PalletBarcode;
                inobj.Priority = 9999;
                inobj.Qty = invobj.AvailableQty ?? 0;
                inobj.FinishedQty = 0;
                inobj.BusinessType = (int)EmBusinessType.Inventory;
                inobj.RelatedOrderDetailId = sdobj.Id;
                inobj.CreateUserId = m.NowUserId;
                inobj.CreateUserName = m.NowUserName;
                _instructRepository.AddEntity(inobj);
                #endregion
                #region 添加上架单
                string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                string putawayCode = "STP" + str;
                PutawayOrder putawayOrder = new PutawayOrder();
                putawayOrder.Id = YitIdHelper.NextId();
                putawayOrder.Code = putawayCode;
                putawayOrder.BillType = 3;
                putawayOrder.RelatedOrderDetailId = sdobj.Id;
                putawayOrder.PalletBarcode = invobj.PalletBarcode;
                putawayOrder.LocationCode = invobj.LocationCode;
                putawayOrder.LocationDepth = invobj.LocationDepth == 0 ? null : invobj.LocationDepth;
                putawayOrder.Status = 4;
                putawayOrder.Qty = invobj.AvailableQty;
                putawayOrder.MaterialId = invobj.MaterialId;
                putawayOrder.MaterialCode = invobj.MaterialCode;
                putawayOrder.MaterialName = invobj.MaterialName;
                putawayOrder.MaterialKeyId = invobj.MaterialKeyId;
                putawayOrder.SourceType = 4;
                putawayOrder.CreateDate = DateTime.Now;
                putawayOrder.Roadway = invobj.RoutewayId.ToString();

                _putawayOrderRepository.AddEntity(putawayOrder);
                result = _unitOfWork.SaveChangesEntity();
                #endregion     
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public bool StaticFinishStocktakingOrders(string putcode, out string message)
        {
            message = "";
            var putobj = _putawayOrderRepository.QueryEntityWhere(x => x.Code == putcode && x.SourceType == 4 && x.Status == 4);
            if (putobj == null)
            {
                message = "找不到上架单！";
                return false;
            }
            var instructlist = _instructRepository.GetEntityWhereAll(x => x.PalletBarcode == putobj.PalletBarcode && x.Status == 2 && x.InstructType == 4).ToList();
            if (!instructlist.Any())
            {
                message = "未查询到指令！";
                return false;
            }
            bool result;
            try
            {
                foreach (var instruct in instructlist)
                {
                    instruct.Status = 4;
                    instruct.EndTime = DateTime.Now;
                    //盘点单id
                    long? sid = instruct.RelatedOrderId;
                    if (sid == null)
                    {
                        message = "盘点单id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var sobj = _stocktakingOrderRepository.QueryEntityById(sid ?? 0);
                    if (sobj == null)
                    {
                        message = "未查询到单号";
                        return false;
                    }
                    sobj.Status = 4;
                    _stocktakingOrderRepository.UpdEntity(sobj);
                    if (instruct.RelatedOrderDetailId == null)
                    {
                        message = "盘库单明细id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var sdobj = _stocktakingOrderDetailRepository.QueryEntityById((long)instruct.RelatedOrderDetailId);
                    if (sdobj == null)
                    {
                        message = "未查询到单号" + sobj.OrderSn + "的盘点单详情！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    sdobj.Status = 4;
                    sdobj.Step = 4;
                    //拿到库存id
                    long? invid = sdobj.InventoryId;
                    if (invid == null)
                    {
                        message = "出库明细中库存id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    Inventory? inventoryModel = _inventoryRepository.QueryEntityById((long)invid);
                    if (inventoryModel == null)
                    {
                        message = "未查询到库存信息！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    decimal? startQty = inventoryModel.AvailableQty;
                    decimal? changeQty = instruct.Qty;
                    #region 库存流水
                    //var inventoryLog = new InventoryLog
                    //{
                    //    Id = YitIdHelper.NextId(),
                    //    SourceType = 2,
                    //    SourceSn = sobj.OrderSn,
                    //    WarehouseId = inventoryModel.WarehouseId,
                    //    WarehouseName = inventoryModel.WarehouseName,
                    //    AreaName = inventoryModel.AreaName,
                    //    LocationCode = inventoryModel.LocationCode,
                    //    PalletBarcode = inventoryModel.PalletBarcode,
                    //    MaterialId = inventoryModel.MaterialId,
                    //    MaterialCode = inventoryModel.MaterialCode,
                    //    MaterialName = inventoryModel.MaterialName,
                    //    BatchNo = inventoryModel.BatchNo,
                    //    StartQty = startQty,
                    //    ChangeQty = -changeQty,
                    //    EndQty = startQty - changeQty,
                    //    BaseUnitId = inventoryModel.UnitId,
                    //    BaseUnitName = inventoryModel.UnitName,
                    //    CreateDate = DateTime.Now,
                    //};
                    //_inventoryLogRepository.AddEntity(inventoryLog);
                    #endregion
                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                    {
                        message = "保存库存流水失败！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                }
                var ilist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == putobj.PalletBarcode);
                foreach (var item in ilist)
                {
                    item.Status = 1;
                    item.IsLock = false;
                }
                var putlist = _putawayOrderRepository.GetEntityWhereAll(x => x.SourceType == 4 && x.Status == 4 && x.PalletBarcode == putobj.PalletBarcode);
                foreach (var item in putlist)
                {
                    item.Status = 5;
                    _putawayOrderRepository.UpdEntity(item);
                }
                if (!_unitOfWork.SaveChangesEntity())
                    return false;
                return true;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public bool FinishStocktakingOrders(string putcode, out string message)
        {
            _unitOfWork.BeginTransaction();
            try
            {
                bool result = StaticFinishStocktakingOrders(putcode, out message);
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }
        #endregion
    }
}
